package com.yusiji.study;

import org.apache.dubbo.common.constants.CommonConstants;
import org.apache.dubbo.common.extension.Activate;
import org.apache.dubbo.rpc.*;

import java.util.*;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.stream.Collectors;

@Activate(group = {CommonConstants.CONSUMER})
public class TPMonitorFilter implements Filter {
    static {
        System.out.println("定时器开始执行");
        timer();
    }

    private static Map<String, List<MethodResult>> result =  new ConcurrentHashMap<>();


    @Override
    public Result invoke(Invoker<?> invoker, Invocation invocation) throws RpcException {
        long start = System.currentTimeMillis();
        String methodName = invocation.getMethodName();
        Result invoke = invoker.invoke(invocation);
        long doTime = System.currentTimeMillis()-start;

        MethodResult methodResult = new MethodResult(doTime,System.currentTimeMillis(),methodName);
        if(result.containsKey(methodName)){
            result.get(methodName).add(methodResult);
        }else{
            List<MethodResult> methodResults =  new CopyOnWriteArrayList<>();
            methodResults.add(methodResult);
            result.put(methodName,methodResults);
        }
        return invoke;
    }

    public static void timer() {
        Timer timer = new Timer();
        timer.schedule(new TimerTask() {
            public void run() {
                getTPN();
                System.out.println("-------设定要指定任务--------");
            }
        }, 0,5000);// 设定指定的时间time,此处为5000毫秒
    }

    public static void getTPN(){
        System.out.println("-------begin--------");
        if(result.size()>0){
            long beforeOneMinutus = System.currentTimeMillis() -60000;
            //遍历map
            Set<Map.Entry<String, List<MethodResult>>> entries = result.entrySet();
            for (Map.Entry entry:entries){
                List<MethodResult> value = (List<MethodResult>) entry.getValue();
                for (MethodResult methodResult : value) {
                    long endtime = methodResult.getEndtime();
                    if(endtime<beforeOneMinutus){
                        value.remove(methodResult);
                    }
                }

                List<MethodResult> sortValue = value.stream().sorted((v1,v2)-> {
                    if(v1.getGetTime() < v2.getGetTime()){
                        return -1;
                    }else{
                        return 1;
                    }
                }).collect(Collectors.toList());
                int size = sortValue.size();
                if(size>0){
                    int tp90 = (int) (size*0.9);
                    int tp99 = (int) (size*0.99);
                    System.out.println(entry.getKey()+": tp90 ===========>"+sortValue.get(tp90).getGetTime());
                    System.out.println(entry.getKey()+": tp99 ===========>"+sortValue.get(tp99).getGetTime());
                }




            }
        }

    }


}
